﻿using System;
using System.Linq;
using System.Text;
using AudioComponent;
using EntitiesAndGameState;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Graphics;
using Services;
using Utilities.Menu.UIElements;
using WAG.Menu;
using WAG.Resources;

namespace WAG
{

    using Game = Microsoft.Xna.Framework.Game;

    /// <summary>
    /// La classe UIRenderer si occupa di disegnare l'interfaccia: punteggi, informazioni utili, bottoni (il pulsante "QUIT GAME") etc.
    /// UIRenderer utilizza il servizio di IStateProvider per conoscere punteggio, numero di vite residue del giocatore, etc.
    /// </summary>
    public class UILandscape : DrawableGameComponent
    {
        public static int PrimaryActive = 0, SecondaryActive = 0;

        Matrix screen_transform;
        SpriteBatch sprite_batch;
        SpriteFont title_font, arial14, menu_f;
        Texture2D white_pixel, ship_icon, life_bar, life_back_ground_bar, green_trash_bin, yellow_trash_bin, blue_trash_bin, manhole, smog, trash_bin_state_bar;
        Button resume, quit_to_menu, controls, audio, quit_and_save;
        SoundEffect click;
        Texture2D tutorial1, tutorial2, tutorial3, tutorial4, tutorial5, tutorial6, tutorial7, tutorial8, tutorial9, tutorial10;
        int tutorial_page = 0;
        Rectangle top_left, middle_left, mini_top_left, mini_middle_left, mini_bottom_left, mini_top_middle, mini_bottom_middle;

        float alpha = 0.0f;
        //Texture2D single_tap, double_tap, long_tap;
        SpriteFont font_32, font_16, font12;
        Button back;
       // Button[] weapons, wtype;
        Box box;
        Texture2D ui_dock, overlay_dock, bar_block, score_dock, bubble_wave;
        Rectangle pause_rect, top_menu_rect, bubble_wave_rect, green_trash_bin_rect, blue_trash_bin_rect, yellow_trash_bin_rect, manhole_rect, trash_bin_state_bar_rect;
        Vector2 box_dimension = new Vector2(200, 200);
        Vector2 initial_box_pos = new Vector2(1100, 252.5f), final_box_pos = new Vector2(590, 252.5f);
        GraphicsDeviceManager graphics;
        Button[] tutorial_buttons;

      //  xAnimations anim1, anim2, anim3;

        PlayState state;

        public UILandscape(Microsoft.Xna.Framework.Game game)
            : base(game)
        {
            this.UpdateOrder = (int)ComponentOrders.UI;
            this.DrawOrder = (int)ComponentOrders.UI;

        }

        IStateProvider<BaseLevelStats> state_provider;
        CameraProvider camera;
        InputManager input_manager;
        public override void Initialize()
        {
            state_provider = Game.Services.GetService(typeof(IStateProvider<BaseLevelStats>))
              as IStateProvider<BaseLevelStats>;
            (Game.Services.GetService(typeof(IInputManager)) as IInputManager).OnTap += new InputManager.Tap(on_tap);
            graphics = (GraphicsDeviceManager)Game.Services.GetService(typeof(GraphicsDeviceManager));

            input_manager = Game.Services.GetService(typeof(IInputManager)) as InputManager;

            camera = Game.Services.GetService(typeof(CameraProvider)) as CameraProvider;

            state = PlayState.Playing;

            base.Initialize();
        }

        protected override void Dispose(bool disposing)
        {
            Game.Services.RemoveService(typeof(IInputManager));

            //graphics.SupportedOrientations = DisplayOrientation.Portrait;
            //graphics.PreferredBackBufferWidth = 480;
            //graphics.PreferredBackBufferHeight = 800;

            //graphics.ApplyChanges();

            base.Dispose(disposing);
        }

        protected override void LoadContent()
        {
          audio_manager = Game.Services.GetService(typeof(IAudioManager)) as AudioManager;
          sprite_batch = (SpriteBatch)Game.Services.GetService(typeof(SpriteBatch));
          screen_transform = Matrix.CreateScale(GraphicsDevice.Viewport.Width / 800,
              GraphicsDevice.Viewport.Height / 480, 1.0f);

          title_font = Game.Content.Load<SpriteFont>(@"fonts\OCRAExtended28");
          arial14 = Game.Content.Load<SpriteFont>(@"fonts\arial14ptx");
          menu_f = Game.Content.Load<SpriteFont>(@"fonts\OCRAExtended18");
          white_pixel = Game.Content.Load<Texture2D>(@"UI\whitepixel");
          ship_icon = Game.Content.Load<Texture2D>(@"UI\ship_ico_v");
          click = Game.Content.Load<SoundEffect>(@"Audio\Bip");
          ui_dock = Game.Content.Load<Texture2D>(@"UI\upper_dock_v");
          score_dock = Game.Content.Load<Texture2D>(@"UIWAG\score");
          menu_dock = Game.Content.Load<Texture2D>(@"UIWAG\menu");
          bar_block = Game.Content.Load<Texture2D>(@"UI\bar_block_v");
          life_bar = Game.Content.Load<Texture2D>(@"UIWAG\life_bar");
          life_back_ground_bar = Game.Content.Load<Texture2D>(@"UIWAG\life_back_ground_bar");
          //yellow_glow = Game.Content.Load<Texture2D>(@"UI\WSelector\yellow_glow");
          //white_glow = Game.Content.Load<Texture2D>(@"UI\WSelector\white_glow");
          //f_weapon_circle = Game.Content.Load<Texture2D>(@"UI\WSelector\weapon_circle_v");
          //s_weapon_circle = Game.Content.Load<Texture2D>(@"UI\WSelector\b_weapon_circle");
          overlay_dock = Game.Content.Load<Texture2D>(@"UI\upper_dock_overlay");
          top_menu_border = Game.Content.Load<Texture2D>(@"UIWAG\top_screen_bar");
          audio_on = Game.Content.Load<Texture2D>(@"UIWAG\game_audio_on");
          audio_off = Game.Content.Load<Texture2D>(@"UIWAG\game_audio_off");
          bubble_wave = Game.Content.Load<Texture2D>(@"UIWAG\bubble_wave");
          //double_tap = Game.Content.Load<Texture2D>("Menu/double_tap");
          //single_tap = Game.Content.Load<Texture2D>("Menu/single_tap");
          //long_tap = Game.Content.Load<Texture2D>("Menu/long_tap");
          font_32 = Game.Content.Load<SpriteFont>("Fonts/OCRAExtended30");
          font_16 = Game.Content.Load<SpriteFont>("Fonts/OCRAExtended16");
          font12 = Game.Content.Load<SpriteFont>("Fonts/OCRAExtended12");
          yellow_trash_bin = Game.Content.Load<Texture2D>(@"UIWAG\yellow_trash_bin");
          green_trash_bin = Game.Content.Load<Texture2D>(@"UIWAG\green_trash_bin");
          blue_trash_bin = Game.Content.Load<Texture2D>(@"UIWAG\blue_trash_bin");
          manhole = Game.Content.Load<Texture2D>(@"UIWAG\manhole");
          trash_bin_state_bar = Game.Content.Load<Texture2D>(@"UIWAG\trash_bin_state_bar");

          tutorial1 = Game.Content.Load<Texture2D>(@"Tutorial\Tutorial1");
          tutorial2 = Game.Content.Load<Texture2D>(@"Tutorial\Tutorial2");
          tutorial3 = Game.Content.Load<Texture2D>(@"Tutorial\Tutorial3");
          tutorial4 = Game.Content.Load<Texture2D>(@"Tutorial\Tutorial4");
          tutorial5 = Game.Content.Load<Texture2D>(@"Tutorial\Tutorial5");
          tutorial6 = Game.Content.Load<Texture2D>(@"Tutorial\Tutorial6");
          tutorial7 = Game.Content.Load<Texture2D>(@"Tutorial\Tutorial7");
          tutorial8 = Game.Content.Load<Texture2D>(@"Tutorial\Tutorial8");
          tutorial9 = Game.Content.Load<Texture2D>(@"Tutorial\Tutorial9");
          tutorial10 = Game.Content.Load<Texture2D>(@"Tutorial\Tutorial10");

          tutorial_buttons = CreateRightAlignedButtons(new string[] { Strings.Prev, Strings.ExitTutorial, Strings.Next }, 250, 100, 400, 10, 0);

          top_left = new Rectangle(90, 60, 0, 0);
          middle_left = new Rectangle(90, 230, 0, 0);

          mini_top_left = new Rectangle(90, 60, 0, 0);
          mini_middle_left = new Rectangle(90, 170, 0, 0);
          mini_bottom_left = new Rectangle(90, 280, 0, 0);

          mini_top_middle = new Rectangle(400, 115, 0, 0);
          mini_bottom_middle = new Rectangle(400, 215, 0, 0);

          int padding = 10;
          menu_pos = new Vector2(GraphicsDevice.Viewport.Width - menu_dock.Width - padding, 0);
          score_dock_pos = new Vector2(menu_pos.X - score_dock.Width - padding, 0);
          bubble_wave_rect = new Rectangle((int)score_dock_pos.X - bubble_wave.Width - padding, 0, bubble_wave.Width + 10, bubble_wave.Height + 10);
          overlay_dock_pos = Vector2.Zero;

          pause_rect = new Rectangle(GraphicsDevice.Viewport.Width - menu_dock.Width,
              0, menu_dock.Width, menu_dock.Height);

          var resume_sm = menu_f.MeasureString(Strings.Resume);
          resume = new Button
          {
            CollisionBox = new Rectangle(590 + (100 - (int)resume_sm.X / 2) - 10, 261, (int)resume_sm.X + 20, (int)resume_sm.Y + 20),
            Label = Strings.Resume,
            Position = new Vector2(590 + (100 - resume_sm.X / 2.0f), 271)
          };


          var control_sm = menu_f.MeasureString(Strings.PauseMenu_Controls);
          controls = new Button
          {
            CollisionBox = new Rectangle(590 + (100 - (int)control_sm.X / 2), 311, (int)control_sm.X + 20, (int)control_sm.Y + 20),
            Label = Strings.PauseMenu_Controls,
            Position = new Vector2(590 + (100 - control_sm.X / 2.0f), 321)
          };
          var quit_sm = menu_f.MeasureString(Strings.Quit);
          quit_to_menu = new Button
          {
            CollisionBox = new Rectangle(590 + (100 - (int)quit_sm.X / 2), 411, (int)quit_sm.X + 20, (int)quit_sm.Y + 20),
            Label = Strings.Quit,
            Position = new Vector2(590 + (100 - quit_sm.X / 2.0f), 421)
          };
          var quit_save_sm = menu_f.MeasureString(Strings.QuitSave);
          quit_and_save = new Button
          {
            CollisionBox = new Rectangle(590 + (100 - (int)quit_save_sm.X / 2), 361, (int)quit_save_sm.X + 20, (int)quit_save_sm.Y + 20),
            Label = Strings.QuitSave,
            Position = new Vector2(590 + (100 - quit_save_sm.X / 2.0f), 371)
          };

          audio = new Button
          {
            CollisionBox = new Rectangle(padding, 0, audio_on.Width + 10, audio_on.Height + 10),
            Label = Strings.AudioOn,
            Position = new Vector2(padding, 0)
          };

          var back_sm = font_32.MeasureString(Strings.Back);
          back = new Button
          {
            CollisionBox = new Rectangle((int)(GraphicsDevice.Viewport.Width / 2.0f - back_sm.X / 2.0f) - 10, 410,
                (int)back_sm.X + 20, (int)back_sm.Y + 20),
            Label = Strings.Back,
            Position = new Vector2(GraphicsDevice.Viewport.Width / 2.0f - back_sm.X / 2.0f, 420.0f)
          };

          box = new Box(new Texture2D[] { Game.Content.Load<Texture2D>("UI/pause_menu_border"),
            Game.Content.Load<Texture2D>("UI/WhitePixel"), Game.Content.Load<Texture2D>("UI/pause_menu_border") },
              initial_box_pos, box_dimension, Color.Black, 0.7f);


          audio_rect = new Rectangle(padding, 0, audio_on.Width, audio_on.Height);

          life_back_ground_rect = new Rectangle(audio_rect.X + audio_rect.Width, 0, life_back_ground_bar.Width, life_back_ground_bar.Height);
          life_rect = new Rectangle(audio_rect.X + audio_rect.Width, (int)((life_back_ground_bar.Height / 2) - (life_bar.Height / 2)), life_bar.Width, life_bar.Height);
          top_menu_rect = new Rectangle(0, 0, 800, top_menu_border.Height);

          yellow_pos = new Vector2(0, 480 - yellow_trash_bin.Height);
          yellow_trash_bin_rect = new Rectangle((int)yellow_pos.X, (int)yellow_pos.Y, yellow_trash_bin.Width, yellow_trash_bin.Height);

          blue_pos = new Vector2(0, top_menu_rect.Height);
          blue_trash_bin_rect = new Rectangle((int)blue_pos.X, (int)blue_pos.Y, blue_trash_bin.Width, blue_trash_bin.Height);

          green_pos = new Vector2(800 - green_trash_bin.Width, top_menu_rect.Height);
          green_trash_bin_rect = new Rectangle((int)green_pos.X, (int)green_pos.Y, green_trash_bin.Width, green_trash_bin.Height);

          manhole_pos = new Vector2(0,((GraphicsDevice.Viewport.Height + top_menu_rect.Height) / 2) - (manhole.Height / 2));
          manhole_rect = new Rectangle((int)manhole_pos.X, (int)manhole_pos.Y, manhole.Width, manhole.Height);
          trash_bin_state_bar_rect = new Rectangle(400, 240, trash_bin_state_bar.Width, trash_bin_state_bar.Height);
        }

        private bool entering = true;
        private bool entered = false;

        private float dt = 0.0f;
        private float MAX_ANIMATION_ZOOM_TIME = 1.5f;

        private Vector2 yellow_pos = new Vector2();
        private Vector2 blue_pos = new Vector2();
        private Vector2 green_pos = new Vector2();
        private Vector2 manhole_pos = new Vector2();

        public override void Update(GameTime gameTime)
        {
            box.Update((float)gameTime.ElapsedGameTime.TotalSeconds * 3);

            if (state_provider.CurrentState.IsZoomed)
            {
              if (entering)
              {
                //blue animation
                dt += (float)gameTime.ElapsedGameTime.TotalSeconds;

                var dest = new Vector2(blue_pos.X - blue_trash_bin.Width, blue_pos.Y - blue_trash_bin.Height);
                var val = Vector2.SmoothStep(blue_pos, dest, Math.Min(dt / MAX_ANIMATION_ZOOM_TIME, MAX_ANIMATION_ZOOM_TIME));
                blue_trash_bin_rect.X = (int)val.X;
                blue_trash_bin_rect.Y = (int)val.Y;

                dest = new Vector2(yellow_pos.X - yellow_trash_bin.Width, yellow_pos.Y + yellow_trash_bin.Height);
                val = Vector2.SmoothStep(yellow_pos, dest, Math.Min(dt / MAX_ANIMATION_ZOOM_TIME, MAX_ANIMATION_ZOOM_TIME));
                yellow_trash_bin_rect.X = (int)val.X;
                yellow_trash_bin_rect.Y = (int)val.Y;

                dest = new Vector2(green_pos.X + green_trash_bin.Width, green_pos.Y - green_trash_bin.Height);
                val = Vector2.SmoothStep(green_pos, dest, Math.Min(dt / MAX_ANIMATION_ZOOM_TIME, MAX_ANIMATION_ZOOM_TIME));
                green_trash_bin_rect.X = (int)val.X;
                green_trash_bin_rect.Y = (int)val.Y;

                dest = new Vector2(manhole_pos.X - manhole.Width, manhole_pos.Y);
                val = Vector2.SmoothStep(manhole_pos, dest, Math.Min(dt / MAX_ANIMATION_ZOOM_TIME, MAX_ANIMATION_ZOOM_TIME));
                manhole_rect.X = (int)val.X;
                manhole_rect.Y = (int)val.Y;

                var start = new Vector2(1, -1);
                dest = new Vector2(1.5f, -1.5f);                
                val = Vector2.SmoothStep(start, dest, Math.Min(dt / MAX_ANIMATION_ZOOM_TIME, MAX_ANIMATION_ZOOM_TIME));
                Background.relativeHorizontalPositionX = val.X;
                Background.relativeVerticalPositionY = val.Y;

                if (dt >= MAX_ANIMATION_ZOOM_TIME)
                  entering = false;
              }
              else
              {
                entered = true;
              }
            }
            else
            {
              if (entered)
              {
                dt -= (float)gameTime.ElapsedGameTime.TotalSeconds;

                var dest = new Vector2(blue_pos.X - blue_trash_bin.Width, blue_pos.Y - blue_trash_bin.Height);
                var val = Vector2.SmoothStep(blue_pos, dest, Math.Max(dt / MAX_ANIMATION_ZOOM_TIME, 0));
                blue_trash_bin_rect.X = (int)val.X;
                blue_trash_bin_rect.Y = (int)val.Y;

                dest = new Vector2(yellow_pos.X - yellow_trash_bin.Width, yellow_pos.Y + yellow_trash_bin.Height);
                val = Vector2.SmoothStep(yellow_pos, dest, Math.Max(dt / MAX_ANIMATION_ZOOM_TIME, 0));
                yellow_trash_bin_rect.X = (int)val.X;
                yellow_trash_bin_rect.Y = (int)val.Y;

                dest = new Vector2(green_pos.X + green_trash_bin.Width, green_pos.Y - green_trash_bin.Height);
                val = Vector2.SmoothStep(green_pos, dest, Math.Max(dt / MAX_ANIMATION_ZOOM_TIME, 0));
                green_trash_bin_rect.X = (int)val.X;
                green_trash_bin_rect.Y = (int)val.Y;

                dest = new Vector2(manhole_pos.X - manhole.Width, manhole_pos.Y);
                val = Vector2.SmoothStep(manhole_pos, dest, Math.Max(dt / MAX_ANIMATION_ZOOM_TIME, 0));
                manhole_rect.X = (int)val.X;
                manhole_rect.Y = (int)val.Y;

                var start = new Vector2(1, -1);
                dest = new Vector2(1.5f, -1.5f);
                val = Vector2.SmoothStep(start, dest, Math.Max(dt / MAX_ANIMATION_ZOOM_TIME, 0));
                Background.relativeHorizontalPositionX = val.X;
                Background.relativeVerticalPositionY = val.Y;

                if (dt <= 0)
                {
                  entering = true;
                  entered = false;
                }
              }
              else
              {
                dt = 0;
                entering = true;
                entered = false;
              }
            }
          

            if (state == PlayState.Pause) state_provider.Enabled = false;

            base.Update(gameTime);
        }
        AudioManager audio_manager;
        void on_tap(Vector2 tap_position)
        {
            var t_p = tap_position.ToPoint(screen_transform);
            var play_click = false;


            switch (state)
            {

                case PlayState.Controls:
                    for (int i = 0; i < tutorial_buttons.Count(); i++)
                    {

                        var tmp = input_manager.IsBackButtonPressed();

                        if (tutorial_buttons[i].CollisionBox.Contains(t_p) || tmp)
                        {
                            if (i == 0 && (tutorial_page > 0))
                            {
                                play_click = true;
                                tutorial_page--;
                            }
                            else if (i == 1 || tmp)
                            {

                                state = PlayState.Pause;
                                play_click = true;
                                tutorial_page = 0;
                            }
                            else if (i == 2 && (tutorial_page < 4))
                            {
                                play_click = true;
                                tutorial_page++;
                            }
                        }
                    }
                    break;
                case PlayState.Pause:
                    state_provider.Enabled = false;



                    if (resume.CollisionBox.Contains(t_p) || pause_rect.Contains(t_p) || input_manager.IsBackButtonPressed())
                    {
                        state_provider.Enabled = true;
                        state = PlayState.Playing;
                        box.StartTransition(initial_box_pos, box_dimension);
                        audio_manager.resumeAllSounds();
                        play_click = true;
                    }
                    else if (controls.CollisionBox.Contains(t_p))
                    {
                        play_click = true;
                        state = PlayState.Controls;
                    }
                    else if (quit_to_menu.CollisionBox.Contains(t_p))
                    {
                        play_click = true;
                        if (OnQuitToMenu != null)
                        {
                            audio_manager.stopAllSounds();
                            OnQuitToMenu();
                        }
                    }
                    else if (quit_and_save.CollisionBox.Contains(t_p))
                    {
                      var tmp = Leaderboard.GetWakaModeStats();
                      play_click = true;
                      if (state_provider.CurrentState.game_mode == GameMode.Tutorial)
                      {
                        Leaderboard.SaveWakaModeStats(new WakaGarbageModeEntry()
                        {
                          ShowAlwaysTutorial = tmp.ShowAlwaysTutorial,
                          GarbageDestroyed = 0,
                          LevelScore = 0,
                          Level = 0,
                          GreenTrashBinState = 0,
                          YellowTrashBinState = 0,
                          BlueTrashBinState = 0,
                          ManHoleState = 0,
                          EarthLife = 0,
                          TotalGameTime = tmp.TotalGameTime,
                          TimeToNextLevel = 0,
                          AudioState = AudioManager.Volume > 0,
                        }
                        );
                      }
                      else
                      {
                        Leaderboard.SaveWakaModeStats(new WakaGarbageModeEntry()
                        {

                          ShowAlwaysTutorial = tmp.ShowAlwaysTutorial,
                          GarbageDestroyed = state_provider.CurrentScore.GarbageDestroyed,
                          LevelScore = state_provider.CurrentScore.LevelScore,
                          Level = state_provider.CurrentState.level,
                          GreenTrashBinState = state_provider.CurrentState.GreenTrashBinState,
                          YellowTrashBinState = state_provider.CurrentState.YellowTrashBinState,
                          BlueTrashBinState = state_provider.CurrentState.BlueTrashBinState,
                          ManHoleState = state_provider.CurrentState.ManHoleState,
                          EarthLife = Background.EarthLife,
                          TotalGameTime = tmp.TotalGameTime + state_provider.CurrentState.totalgametime,
                          TimeToNextLevel = state_provider.CurrentState.time_to_next_level,
                          AudioState = AudioManager.Volume > 0
                        }
                        );
                      }
                      StateManager.SelectMenu(Game);
                      audio_manager.stopAllSounds();
                      Background.EarthLife = -1;
                    }
                    break;
                case PlayState.Playing:


                    if (pause_rect.Contains(t_p) || input_manager.IsBackButtonPressed())
                    {
                        state_provider.Enabled = false;
                        state = PlayState.Pause;
                        audio_manager.pauseAllSounds();
                        box.StartTransition(final_box_pos, box_dimension);
                        play_click = true;

                    }
                    else if (audio.CollisionBox.Contains(t_p))
                    {

                        if (AudioManager.AudioState)
                        {
                            audio_manager.OnaudioOff();
                        }
                        else
                        {
                            audio_manager.OnaudioOn();
                        }
                    }
                    else if (bubble_wave_rect.Contains(t_p))
                    {
                        if (state_provider.CurrentState.num_of_bubble_wave > 0)
                        {
                            state_provider.CurrentState.num_of_bubble_wave--;
                            state_provider.CurrentState.lunch_shock_wave = true;
                        }
                    }
                    break;
            }
            if (AudioManager.AudioState && play_click)
                click.Play(AudioManager.Volume, 0.0f, 0.0f);
        }


        public event Action OnQuitToMenu;
        static StringBuilder score_stringB = new StringBuilder("0");

        Color final_bar_color = new Color(18, 255, 0), life_bar_color = new Color(135, 0, 3);
        Color life_color = Color.Green;
        Color grow_color = Color.White;

        public override void Draw(GameTime gameTime)
        {
            sprite_batch.Begin(SpriteSortMode.Deferred, null, null, null, null, null, screen_transform);

            switch (state)
            {
                case PlayState.Playing:
                    DrawGame(gameTime);
                    break;
                case PlayState.Pause:
                    DrawGame(gameTime);
                    if (!box.InTransition) alpha = MathHelper.Clamp(alpha + (float)gameTime.ElapsedGameTime.TotalSeconds * 8.0f, 0.0f, 1.0f);
                    DrawPauseMenu();
                    break;
                case PlayState.Controls:
                    DrawControls();
                    break;
            }

            sprite_batch.End();

            base.Draw(gameTime);
        }


        StringBuilder s1 = new StringBuilder(), s2 = new StringBuilder();

        #region Draw Helper

        Vector2 score_dock_pos, score_pos = new Vector2(0, 5), bubble_pos = new Vector2(0, 5), menu_pos, ui_dock_pos = new Vector2(0, 0);
        Rectangle life_rect, life_back_ground_rect, audio_rect;

        private void DrawGame(GameTime gameTime)
        {

            var colors = new Color[] { Color.Yellow, Color.Green, Color.CornflowerBlue };

            
            sprite_batch.Draw(manhole, manhole_rect, Color.White);
            //green
            trash_bin_state_bar_rect.X = green_trash_bin_rect.X + green_trash_bin.Width - 5;
            trash_bin_state_bar_rect.Y = green_trash_bin_rect.Y + green_trash_bin.Height / 2 - 4;
            if (state_provider.CurrentState.green_trash_unloading_animation > 0)
            {
              var color = Color.Lerp(Color.White, Color.Gray, ((float)Math.Sin(gameTime.TotalGameTime.TotalMilliseconds / 100.0)));
              sprite_batch.Draw(green_trash_bin, green_trash_bin_rect, color);
              color = Color.Lerp(Color.Red, Color.White, ((float)Math.Sin(gameTime.TotalGameTime.TotalMilliseconds / 100.0)));
              trash_bin_state_bar_rect.Width = (int)trash_bin_state_bar.Width;
              sprite_batch.Draw(trash_bin_state_bar, trash_bin_state_bar_rect, null, color, -MathHelper.Pi * (3.0f / 4.0f), Vector2.Zero, SpriteEffects.None, 0);
            }
            else
            {
              sprite_batch.Draw(green_trash_bin, green_trash_bin_rect, Color.White);
              trash_bin_state_bar_rect.Width = (int)((float)trash_bin_state_bar.Width * ((float)state_provider.CurrentState.GreenTrashBinState / (float)State.MAX_GREEN_TRASH_BIN_CAPACITY));
              sprite_batch.Draw(trash_bin_state_bar, trash_bin_state_bar_rect, null, Color.Red, -MathHelper.Pi * (3.0f / 4.0f), Vector2.Zero, SpriteEffects.None, 0);
            }
            //blue
            trash_bin_state_bar_rect.X = blue_trash_bin_rect.X + 2;
            trash_bin_state_bar_rect.Y = blue_trash_bin_rect.Y + blue_trash_bin_rect.Height / 2 - 7;
            if (state_provider.CurrentState.blue_trash_unloading_animation > 0)
            {
              var color = Color.Lerp(Color.White, Color.Gray, ((float)Math.Sin(gameTime.TotalGameTime.TotalMilliseconds / 100.0)));
              sprite_batch.Draw(blue_trash_bin, blue_trash_bin_rect, color);
              color = Color.Lerp(Color.Red, Color.White, ((float)Math.Sin(gameTime.TotalGameTime.TotalMilliseconds / 100.0)));
              trash_bin_state_bar_rect.Width = (int)trash_bin_state_bar.Width;
              sprite_batch.Draw(trash_bin_state_bar, trash_bin_state_bar_rect, null, color, -MathHelper.PiOver4, Vector2.Zero, SpriteEffects.None, 0);
            }
            else
            {
              sprite_batch.Draw(blue_trash_bin, blue_trash_bin_rect, Color.White);
              trash_bin_state_bar_rect.Width = (int)((float)trash_bin_state_bar.Width * ((float)state_provider.CurrentState.BlueTrashBinState / (float)State.MAX_BLUE_TRASH_BIN_CAPACITY));
              sprite_batch.Draw(trash_bin_state_bar, trash_bin_state_bar_rect, null, Color.Red, -MathHelper.PiOver4, Vector2.Zero, SpriteEffects.None, 0);
            }
            //yellow
            trash_bin_state_bar_rect.X = yellow_trash_bin_rect.X + yellow_trash_bin.Width / 2 - 10;
            trash_bin_state_bar_rect.Y = yellow_trash_bin_rect.Y + yellow_trash_bin.Height - 2;
            if (state_provider.CurrentState.yellow_trash_unloading_animation > 0)
            {
                var color = Color.Lerp(Color.White, Color.Gray, ((float)Math.Sin(gameTime.TotalGameTime.TotalMilliseconds / 100.0)));
                sprite_batch.Draw(yellow_trash_bin, yellow_trash_bin_rect, color);
                color = Color.Lerp(Color.Red, Color.White, ((float)Math.Sin(gameTime.TotalGameTime.TotalMilliseconds / 100.0)));
                trash_bin_state_bar_rect.Width = (int)trash_bin_state_bar.Width;
                sprite_batch.Draw(trash_bin_state_bar, trash_bin_state_bar_rect, null, color, -MathHelper.Pi * (3.0f / 4.0f), Vector2.Zero, SpriteEffects.None, 0);
            }
            else
            {
                sprite_batch.Draw(yellow_trash_bin, yellow_trash_bin_rect, Color.White);
                trash_bin_state_bar_rect.Width = (int)((float)trash_bin_state_bar.Width * ((float)state_provider.CurrentState.YellowTrashBinState / (float)State.MAX_YELLOW_TRASH_BIN_CAPACITY));
                sprite_batch.Draw(trash_bin_state_bar, trash_bin_state_bar_rect, null, Color.Red, -MathHelper.Pi * (3.0f / 4.0f), Vector2.Zero, SpriteEffects.None, 0);
            }

            //vacum
            trash_bin_state_bar_rect.X = manhole_rect.X + manhole.Width / 3 - 8;
            trash_bin_state_bar_rect.Y = manhole_rect.Y + manhole.Height - 17;
            trash_bin_state_bar_rect.Width = (int)((float)trash_bin_state_bar.Width * (MathHelper.Min((float)state_provider.CurrentState.ManHoleState / (float)State.MAN_HOLE_CAPACITY, (float)State.MAN_HOLE_CAPACITY)));
            sprite_batch.Draw(trash_bin_state_bar, trash_bin_state_bar_rect, null, Color.Red, MathHelper.Pi * (3.0f / 2.0f), Vector2.Zero, SpriteEffects.None, 0);

            sprite_batch.Draw(top_menu_border, top_menu_rect, Color.White);

            sprite_batch.Draw(life_back_ground_bar, life_back_ground_rect, Color.White);
            life_rect.Width = (int)(life_bar.Width * (Math.Max(0.0f, Background.EarthLife) / Background.MAX_EARTH_LIFE));
            sprite_batch.Draw(life_bar, life_rect, Color.White);

            sprite_batch.Draw(score_dock, score_dock_pos, Color.White);
            sprite_batch.Draw(menu_dock, menu_pos, Color.White);

            //---------obrobrio!!
            var tmp1 = bubble_wave_rect.Width;
            var tmp2 = bubble_wave_rect.Height;
            bubble_wave_rect.Width = bubble_wave_rect.Width - 10;
            bubble_wave_rect.Height = bubble_wave_rect.Height -10;
            bubble_pos.X = bubble_wave_rect.Center.X;
            sprite_batch.Draw(bubble_wave, bubble_wave_rect, Color.White);
            bubble_wave_rect.Width = tmp1;
            bubble_wave_rect.Height = tmp2;
            //---------

            var score_val = state_provider.CurrentScore.LevelScore.ToString();
            score_pos.X = score_dock_pos.X - menu_f.MeasureString(score_val).X / 2.0f + score_dock.Width / 2;
            sprite_batch.DrawString(menu_f, score_val, score_pos, Color.White);

            var bubble_val = state_provider.CurrentState.num_of_bubble_wave.ToString();
            bubble_pos.X -= menu_f.MeasureString(bubble_val).X / 2.0f; // + bubble_wave.Width / 2;
            //sprite_batch.DrawString(menu_f, state_provider.CurrentState.num_of_bubble_wave.ToString(), new Vector2(bubble_wave_rect.Center.X - 3, bubble_wave_rect.Center.Y - 11), Color.Black);
            sprite_batch.DrawString(menu_f, bubble_val, bubble_pos, Color.White);
            

            var audio_manager = Game.Services.GetService(typeof(IAudioManager)) as AudioManager;

            if (AudioManager.AudioState)
                sprite_batch.Draw(audio_on, audio_rect, Color.White);
            else
                sprite_batch.Draw(audio_off, audio_rect, Color.White);

            box.Draw(sprite_batch);
        }

        private Texture2D menu_dock, top_menu_border, audio_off, audio_on;
        private Vector2 overlay_dock_pos;
        

        private void DrawPauseMenu()
        {
            if (!box.InTransition)
            {
                sprite_batch.DrawString(menu_f, resume.Label, resume.Position, Color.White * alpha);
                sprite_batch.DrawString(menu_f, controls.Label, controls.Position, Color.White * alpha);
                sprite_batch.DrawString(menu_f, quit_to_menu.Label, quit_to_menu.Position, Color.White * alpha);
                sprite_batch.DrawString(menu_f, quit_and_save.Label, quit_and_save.Position, Color.White * alpha);
            }
        }

        private Button[] CreateRightAlignedButtons(string[] labels, int offset, int starting_x, int starting_y, int padding, int align_val)
        {
            Button[] bs = new Button[labels.Count()];

            for (int i = 0; i < bs.Count(); i++)
            {
                Vector2 label_measure = font_32.MeasureString(labels[i]);
                var x = starting_x + i * offset;
                //int x = (int)((w + align_val) / 2.0f - label_measure.X / 2.0f);
                int y = starting_y;
                bs[i] = new Button()
                {
                    CollisionBox = new Rectangle(x, y, (int)label_measure.X, (int)label_measure.Y),
                    Label = labels[i],
                    Position = new Vector2(x, y)
                };
            }

            return bs;
        }

        private void DrawControls()
        {

            sprite_batch.Draw(white_pixel, new Rectangle(0, 0, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height),
              Color.Black * MathHelper.Min(alpha, 0.8f));


            switch (tutorial_page)
            {
                case 0:

                    sprite_batch.DrawString(font_16, Strings.TitleTutorial5 + " \n" + Strings.Tutorial9.Replace("\\n", "\n"),
                        new Vector2(421, top_left.Y), Color.DarkGray * alpha);
                    sprite_batch.DrawString(font_16, Strings.TitleTutorial5 + " \n" + Strings.Tutorial9.Replace("\\n", "\n"),
                        new Vector2(420, top_left.Y), Color.White * alpha);

                    sprite_batch.DrawString(font_16, Strings.Tutorial10.Replace("\\n", "\n"),
                        new Vector2(421, middle_left.Y), Color.DarkGray * alpha);
                    sprite_batch.DrawString(font_16, Strings.Tutorial10.Replace("\\n", "\n"),
                        new Vector2(420, middle_left.Y), Color.White * alpha);


                    top_left.Width = tutorial9.Width;
                    top_left.Height = tutorial9.Height;
                    sprite_batch.Draw(tutorial9, top_left, Color.White * alpha);

                    middle_left.Width = tutorial10.Width;
                    middle_left.Height = tutorial10.Height;
                    sprite_batch.Draw(tutorial10, middle_left, Color.White * alpha);

                    for (int i = 1; i < tutorial_buttons.Count(); i++)
                    {
                        sprite_batch.DrawString(font_32, tutorial_buttons[i].Label, tutorial_buttons[i].Position + Vector2.One * 2.5f, Color.Black * alpha);
                        sprite_batch.DrawString(font_32, tutorial_buttons[i].Label, tutorial_buttons[i].Position, Color.White * alpha);
                    }

                    break;
                case 1:

                    sprite_batch.DrawString(font_16, Strings.TitleTutorial1 + " \n" + Strings.Tutorial1.Replace("\\n", "\n"),
                        new Vector2(421, top_left.Y), Color.DarkGray * alpha);
                    sprite_batch.DrawString(font_16, Strings.TitleTutorial1 + " \n" + Strings.Tutorial1.Replace("\\n", "\n"),
                        new Vector2(420, top_left.Y), Color.White * alpha);

                    sprite_batch.DrawString(font_16, Strings.Tutorial2.Replace("\\n", "\n"),
                        new Vector2(421, middle_left.Y), Color.DarkGray * alpha);
                    sprite_batch.DrawString(font_16, Strings.Tutorial2.Replace("\\n", "\n"),
                        new Vector2(420, middle_left.Y), Color.White * alpha);


                    top_left.Width = tutorial1.Width;
                    top_left.Height = tutorial1.Height;
                    sprite_batch.Draw(tutorial1, top_left, Color.White * alpha);

                    middle_left.Width = tutorial2.Width;
                    middle_left.Height = tutorial2.Height;
                    sprite_batch.Draw(tutorial2, middle_left, Color.White * alpha);

                    for (int i = 0; i < tutorial_buttons.Count(); i++)
                    {
                        sprite_batch.DrawString(font_32, tutorial_buttons[i].Label, tutorial_buttons[i].Position + Vector2.One * 2.5f, Color.Black * alpha);
                        sprite_batch.DrawString(font_32, tutorial_buttons[i].Label, tutorial_buttons[i].Position, Color.White * alpha);
                    }

                    break;
                case 2:

                    sprite_batch.DrawString(font_16, Strings.TitleTutorial2 + " \n" + Strings.Tutorial3.Replace("\\n", "\n"),
                        new Vector2(421, top_left.Y), Color.DarkGray * alpha);
                    sprite_batch.DrawString(font_16, Strings.TitleTutorial2 + " \n" + Strings.Tutorial3.Replace("\\n", "\n"),
                        new Vector2(420, top_left.Y), Color.White * alpha);

                    sprite_batch.DrawString(font_16, Strings.Tutorial4.Replace("\\n", "\n"),
                        new Vector2(421, middle_left.Y), Color.DarkGray * alpha);
                    sprite_batch.DrawString(font_16, Strings.Tutorial4.Replace("\\n", "\n"),
                        new Vector2(420, middle_left.Y), Color.White * alpha);


                    top_left.Width = tutorial3.Width;
                    top_left.Height = tutorial3.Height;
                    sprite_batch.Draw(tutorial3, top_left, Color.White * alpha);

                    middle_left.Width = tutorial4.Width;
                    middle_left.Height = tutorial4.Height;
                    sprite_batch.Draw(tutorial4, middle_left, Color.White * alpha);

                    for (int i = 0; i < tutorial_buttons.Count(); i++)
                    {
                        sprite_batch.DrawString(font_32, tutorial_buttons[i].Label, tutorial_buttons[i].Position + Vector2.One * 2.5f, Color.Black * alpha);
                        sprite_batch.DrawString(font_32, tutorial_buttons[i].Label, tutorial_buttons[i].Position, Color.White * alpha);
                    }

                    break;
                case 3:

                    sprite_batch.DrawString(font_16, Strings.TitleTutorial3 + " \n" + Strings.Tutorial5.Replace("\\n", "\n"),
                        new Vector2(421, top_left.Y), Color.DarkGray * alpha);
                    sprite_batch.DrawString(font_16, Strings.TitleTutorial3 + " \n" + Strings.Tutorial5.Replace("\\n", "\n"),
                        new Vector2(420, top_left.Y), Color.White * alpha);

                    sprite_batch.DrawString(font_16, Strings.Tutorial6.Replace("\\n", "\n"),
                        new Vector2(421, middle_left.Y), Color.DarkGray * alpha);
                    sprite_batch.DrawString(font_16, Strings.Tutorial6.Replace("\\n", "\n"),
                        new Vector2(420, middle_left.Y), Color.White * alpha);


                    top_left.Width = tutorial5.Width;
                    top_left.Height = tutorial5.Height;
                    sprite_batch.Draw(tutorial5, top_left, Color.White * alpha);

                    middle_left.Width = tutorial6.Width;
                    middle_left.Height = tutorial6.Height;
                    sprite_batch.Draw(tutorial6, middle_left, Color.White * alpha);
                    
                    for (int i = 0; i < tutorial_buttons.Count(); i++)
                    {
                        sprite_batch.DrawString(font_32, tutorial_buttons[i].Label, tutorial_buttons[i].Position + Vector2.One * 2.5f, Color.Black * alpha);
                        sprite_batch.DrawString(font_32, tutorial_buttons[i].Label, tutorial_buttons[i].Position, Color.White * alpha);
                    }
                    tutorial_buttons[1].Label = tutorial_buttons[1].Label; ;

                    break;
                case 4:

                    sprite_batch.DrawString(font_16, Strings.TitleTutorial4 + " \n" + Strings.Tutorial7.Replace("\\n", "\n"),
                        new Vector2(421, top_left.Y), Color.DarkGray * alpha);
                    sprite_batch.DrawString(font_16, Strings.TitleTutorial4 + " \n" + Strings.Tutorial7.Replace("\\n", "\n"),
                        new Vector2(420, top_left.Y), Color.White * alpha);

                    sprite_batch.DrawString(font_16, Strings.Tutorial8.Replace("\\n", "\n"),
                        new Vector2(421, middle_left.Y), Color.DarkGray * alpha);
                    sprite_batch.DrawString(font_16, Strings.Tutorial8.Replace("\\n", "\n"),
                        new Vector2(420, middle_left.Y), Color.White * alpha);


                    top_left.Width = tutorial7.Width;
                    top_left.Height = tutorial7.Height;
                    sprite_batch.Draw(tutorial7, top_left, Color.White * alpha);

                    middle_left.Width = tutorial8.Width;
                    middle_left.Height = tutorial8.Height;
                    sprite_batch.Draw(tutorial8, middle_left, Color.White * alpha);
                    
                    for (int i = 0; i < tutorial_buttons.Count() - 1; i++)
                    {
                        sprite_batch.DrawString(font_32, tutorial_buttons[i].Label, tutorial_buttons[i].Position + Vector2.One * 2.5f, Color.Black * alpha);
                        sprite_batch.DrawString(font_32, tutorial_buttons[i].Label, tutorial_buttons[i].Position, Color.White * alpha);
                    }
                    tutorial_buttons[1].Label = tutorial_buttons[1].Label;

                    break;
            }
        }

        #endregion

        private float CenterValue(float screen_dim, float item_width)
        {
            return screen_dim / 2.0f - item_width / 2.0f;
        }
    }
}
